package com.whg.es.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.whg.es.dao.NBAPlayerDao;
import com.whg.es.model.NBAPlayer;
import com.whg.es.service.NBAPlayerService;
import com.whg.es.utils.EsUtils;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.PrefixQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.elasticsearch.action.search.SearchRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author whg
 * @create 2023/7/4 18:25
 * @description：
 */
@Service
public class NBAPlayerServiceImpl implements NBAPlayerService {

    private static final String INDEX = "nba_latest";

    private static final int FROM = 0;

    private static final int SIZE = 100;

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private NBAPlayerDao nbaPlayerDao;

    /**
     * 添加运动员
     * @param player
     * @param id
     * @return
     */
    @Override
    public Boolean addPlayer(NBAPlayer player, String id) throws IOException {
        IndexRequest request = new IndexRequest(INDEX)
                .id(id).source(EsUtils.beanToMap(player));
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        System.out.println(JSONObject.toJSON(response));
        return true;
    }

    /**
     * 获取运动员
     * @param id
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> getPlayer(String id) throws IOException {
        GetRequest request = new GetRequest(INDEX,id);
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        return response.getSource();
    }

    /**
     * 更新运动员
     * @param player
     * @param id
     * @return
     */
    @Override
    public Boolean updatePlayer(NBAPlayer player, String id) throws IOException {
        UpdateRequest request = new UpdateRequest(INDEX,id)
                .doc(EsUtils.beanToMap(player));
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        System.out.println(JSONObject.toJSON(response));
        return true;
    }

    /**
     * 删除运动员
     * @param id
     * @return
     * @throws IOException
     */
    @Override
    public Boolean deletePlayer(String id) throws IOException {
        DeleteRequest request = new DeleteRequest(INDEX,id);
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(JSONObject.toJSON(response));
        return true;
    }

    /**
     * 删除所有的运动员
     * @return
     * @throws IOException
     */
    @Override
    public Boolean deleteAllPlayer() throws IOException {
        DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX).setQuery(new MatchAllQueryBuilder());
        BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT);
        System.out.println(JSONObject.toJSON(response));
        return true;
    }

    /**
     * 导入所有的运动员
     * @return
     * @throws IOException
     */
    @Override
    public Boolean importAllPlayer() throws IOException {
        List<NBAPlayer> list = nbaPlayerDao.selectAll();
        for (NBAPlayer player : list){
            addPlayer(player,String.valueOf(player.getId()));
        }
        return true;
    }

    /**
     * 匹配查询运动员
     * @param key
     * @param value
     * @return
     * @throws IOException
     */
    @Override
    public List<NBAPlayer> searchMatch(String key, String value) throws IOException {
        QueryBuilder queryBuilder = QueryBuilders.matchQuery(key, value);
        return handleSearch(queryBuilder);
    }

    /**
     * 精准查询运动员
     * @param key
     * @param value
     * @return
     * @throws IOException
     */
    @Override
    public List<NBAPlayer> searchTerm(String key, String value) throws IOException {
        QueryBuilder queryBuilder = QueryBuilders.termQuery(key, value);
        return handleSearch(queryBuilder);
    }

    /**
     * 前缀查询运动员
     * @param key
     * @param value
     * @return
     * @throws IOException
     */
    @Override
    public List<NBAPlayer> searchPrefix(String key, String value) throws IOException {
        QueryBuilder queryBuilder = QueryBuilders.prefixQuery(key, value);
        return handleSearch(queryBuilder);
    }

    /**
     * 处理查询
     * @param queryBuilder
     * @return
     */
    private List<NBAPlayer> handleSearch(QueryBuilder queryBuilder) throws IOException {
        SearchRequest request = new SearchRequest(INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(queryBuilder);
        builder.from(FROM);
        builder.size(SIZE);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        List<NBAPlayer> list = new ArrayList<>();
        for (SearchHit hit : hits){
            NBAPlayer player = JSONObject.parseObject(hit.getSourceAsString(),NBAPlayer.class);
            list.add(player);
        }
        return list;
    }

}
